(function(angular) {
	'use strict';

	angular.module("fs.storage", [ 'LocalStorageModule' ]).

	constant("StorageConstants", {
		STORAGE_PREFIX : "FS_APP",
		LOG_STORAGE_KEY : "FS_APP_LOG",
		SITE_INFO_STORAGE_KEY : 'FS_SITE_INFO',
		USER_INFO_STORAGE_KEY : 'FS_USER_INFO',
		SYSTEM_INFO_STORAGE_KEY : 'FS_SYSTEM_INFO',
		FORMAT_INFO_STORAGE_KEY : 'FS_FORMAT_INFO',
		MENU_INFO_STORAGE_KEY : 'FS_MENU_INFO',
		MENU_CONFIG_INFO_STORAGE_KEY : 'FS_MENU_CONFIG_INFO',
		SEARCH_CRITERIA_STORAGE_KEY : "FS_APP_SEARCH_CRITERIA",
		HIS_STORAGE_KEY : 'FS_HIS_INFO',
		BACKHIS_STORAGE_KEY : 'FS_BACKHIS_INFO',
		SYSTEM_SETTINGS_KEY : 'FS_SYSTEM_SETTINGS',
		DBD_PANEL_KEY : 'FS_DASHBOARD_PANELS',
		TABLE_KEY : 'FS_TABLES'
	}).

	provider('storageService', storageService).

	config(
			[ 'StorageConstants', 'localStorageServiceProvider', 'storageServiceProvider',
					function(StorageConstants, localStorageServiceProvider, storageServiceProvider) {
						localStorageServiceProvider.setPrefix(StorageConstants.STORAGE_PREFIX).setNotify(true, true);
					} ]);

	storageService.$inject = [ 'StorageConstants' ];
	function storageService(StorageConstants) {
		var privoder = this;
		privoder.logStorageSize = 2000;
		privoder.searchCriteriaStorageSize = 20;
		privoder.searchCriteriaStorageMinutes = 5;
		privoder.hisStorageSize = 200;
		privoder.setLogStorageSize = function(size) {
			privoder.logStorageSize = size;
		};
		privoder.getLogStorageSize = function() {
			return privoder.logStorageSize;
		};
		privoder.setSearchCriteriaStorageSize = function(size) {
			privoder.searchCriteriaStorageSize = size;
		};
		privoder.getSearchCriteriaStorageSize = function() {
			return privoder.searchCriteriaStorageSize;
		};
		privoder.setSearchCriteriaStorageMinutes = function(minutes) {
			privoder.searchCriteriaStorageMinutes = minutes;
		};
		privoder.getSearchCriteriaStorageMinutes = function() {
			return privoder.searchCriteriaStorageMinutes;
		};
		privoder.setHisStorageSize = function(size) {
			privoder.hisStorageSize = size;
		};
		privoder.getHisStorageSize = function() {
			return privoder.hisStorageSize;
		};

		this.$get = [ '$injector', 'localStorageService', '$filter', function($injector, localStorageService, $filter) {
			privoder.localStorageService = localStorageService;
			return {
				clearAllFromSession : clearAllFromSession,
				clearAllFromLocal : clearAllFromLocal,
				clearAllCookie : clearAllCookie,
				setCookie : setCookie,
				getCookie : getCookie,
				removeCookie : removeCookie,
				removeItemFromSession : removeItemFromSession,
				removeItemFromLocal : removeItemFromLocal,
				setItemToSession : setItemToSession,
				getItemFromSession : getItemFromSession,
				setItemToLocal : setItemToLocal,
				getItemFromLocal : getItemFromLocal,
				setLogStorageSize : privoder.setLogStorageSize,
				getLogStorageSize : privoder.getLogStorageSize,
				saveLog : saveLog,
				getLog : getLog,
				saveSearchCriteria : saveSearchCriteria,
				getSearchCriteria : getSearchCriteria,
				saveSiteInfo : saveSiteInfo,
				getSiteInfo : getSiteInfo,
				saveUserInfo : saveUserInfo,
				getUserInfo : getUserInfo,
				saveFormatInfo : saveFormatInfo,
				getFormatInfo : getFormatInfo,
				saveSystemInfo : saveSystemInfo,
				getSystemInfo : getSystemInfo,
				saveMenuInfo : saveMenuInfo,
				getMenuInfo : getMenuInfo,
				saveMenuConfigInfo : saveMenuConfigInfo,
				getMenuConfigInfo : getMenuConfigInfo,
				saveHistory : saveHistory,
				popHistory : popHistory,
				getLastHistory : getLastHistory,
				getSystemSettings : getSystemSettings,
				saveSystemSettings : saveSystemSettings,
				saveDbdPanelSetting : saveDbdPanelSetting,
				getDbdPanelSetting : getDbdPanelSetting,
				saveTableSetting : saveTableSetting,
				getTableSetting : getTableSetting
			};
			function clearAllCookie() {
				privoder.localStorageService.cookie.clearAll();
			}

			function getCookie(key) {
				return privoder.localStorageService.cookie.get(key);
			}

			function setCookie(key, value, daysToExpiry, secure) {
				privoder.localStorageService.cookie.set(key, value, daysToExpiry, secure);
			}

			function removeCookie(key) {
				privoder.localStorageService.cookie.clearAll();
			}

			function clearAllFromSession(type) {
				privoder.localStorageService.clearAll(null, 'sessionStorage');
			}

			function clearAllFromLocal(type) {
				privoder.localStorageService.clearAll(null, 'localStorage');
			}

			function removeItemFromSession(key) {
				privoder.localStorageService.remove(key, 'sessionStorage');
			}

			function removeItemFromLocal(key) {
				privoder.localStorageService.remove(key, 'localStorage');
			}

			function setItemToSession(key, value) {
				if (value == 'I18N_VALIDAQTION_RESOURCES' || key ==  'I18N_RESOURCES') {
							console.log(value)
						}
				privoder.localStorageService.set(key, value, 'sessionStorage');
			}

			function getItemFromSession(key) {
				return privoder.localStorageService.get(key, 'sessionStorage');
			}

			function setItemToLocal(key, value) {
				if (value == 'I18N_VALIDAQTION_RESOURCES' || key ==  'I18N_RESOURCES') {
					console.log(value)
				}
				privoder.localStorageService.set(key, value, 'localStorage');
			}

			function getItemFromLocal(key) {
				return privoder.localStorageService.get(key, 'localStorage');
			}

			function saveLog(logContent) {
				if (!logContent)
					return;
				var log = getLog();
				if (log.length < privoder.getLogStorageSize()) {
					log.push(logContent);
				} else {
					log.shift();
					log.push(logContent);
				}
				setItemToSession(StorageConstants.LOG_STORAGE_KEY, angular.toJson(log));
			}

			function getLog() {
				var logContent = getItemFromSession(StorageConstants.LOG_STORAGE_KEY) || "[]";
				return angular.fromJson(logContent);
			}

			function saveSearchCriteria(searchCriteria) {
				var i, searchCriteriaList;
				if (searchCriteria) {
					searchCriteria = angular.copy(searchCriteria);
					searchCriteriaList = getSearchCriteriaList();
					for (i = 0; i < searchCriteriaList.length; i++) {
						if (searchCriteriaList[i].$state == searchCriteria.$state) {
							searchCriteria._storageDate = new Date().getTime();
							formatDate(searchCriteria);
							searchCriteriaList[i] = searchCriteria;
							setItemToSession(StorageConstants.SEARCH_CRITERIA_STORAGE_KEY, angular.toJson(searchCriteriaList));
							delete searchCriteria._storageDate;
							break;
						}
					}
					if (i < searchCriteriaList.length)
						return;
					if (searchCriteriaList.length < privoder.getSearchCriteriaStorageSize()) {
						searchCriteria._storageDate = new Date().getTime();
						formatDate(searchCriteria);
						searchCriteriaList.push(searchCriteria);
					} else {
						searchCriteriaList.shift();
						searchCriteria._storageDate = new Date().getTime();
						formatDate(searchCriteria);
						searchCriteriaList.push(searchCriteria);
					}
					setItemToSession(StorageConstants.SEARCH_CRITERIA_STORAGE_KEY, angular.toJson(searchCriteriaList));
					delete searchCriteria._storageDate;
				}
			}

			function getSearchCriteriaList() {
				var i, searchCriteriaList = getItemFromSession(StorageConstants.SEARCH_CRITERIA_STORAGE_KEY);
				searchCriteriaList = angular.fromJson(searchCriteriaList) || [];
				for (i = 0; i < searchCriteriaList.length; i++) {
					parseDate(searchCriteriaList[i]);
				}
				return searchCriteriaList;
			}

			function getSearchCriteria(state) {
				var i, searchCriteriaList;
				if (!state) {
					return undefined;
				}
				searchCriteriaList = getSearchCriteriaList();
				for (i = 0; i < searchCriteriaList.length; i++) {
					if (searchCriteriaList[i].$state == state) {
						if(searchCriteriaList[i]._storageDate < (new Date().getTime() - privoder.searchCriteriaStorageMinutes * 60 * 1000)){
							return undefined;
						};
						delete searchCriteriaList[i]._storageDate;
						return searchCriteriaList[i];
					}
				}
			}

			function saveSiteInfo(siteInfo) {
				var formatService, formatInfo;
				if (siteInfo) {
					formatService = $injector.get('formatService');
					formatInfo = getFormatInfo();
					siteInfo.bizDate = formatService.formatDate(siteInfo.bizDate, formatInfo.longTimestamp);
					siteInfo.cutoffTime = formatService.formatDate(siteInfo.cutoffTime, formatInfo.longTimestamp);
					siteInfo.eodDate = formatService.formatDate(siteInfo.eodDate, formatInfo.longTimestamp);
					setItemToSession(StorageConstants.SITE_INFO_STORAGE_KEY, angular.toJson(siteInfo));
				}
			}

			function getSiteInfo() {
				var formatService, formatInfo, siteInfo = getItemFromSession(StorageConstants.SITE_INFO_STORAGE_KEY) || "{}";
				siteInfo = angular.fromJson(siteInfo);
				if (siteInfo) {
					formatService = $injector.get('formatService');
					formatInfo = getFormatInfo();
					siteInfo.bizDate = formatService.parseDate(siteInfo.bizDate, formatInfo.longTimestamp);
					siteInfo.cutoffTime = formatService.parseDate(siteInfo.cutoffTime, formatInfo.longTimestamp);
					siteInfo.eodDate = formatService.parseDate(siteInfo.eodDate, formatInfo.longTimestamp);
				}
				return siteInfo;
			}
			
			function saveSystemInfo(systemInfo) {
				if (systemInfo)
					setItemToSession(StorageConstants.SYSTEM_INFO_STORAGE_KEY, angular.toJson(systemInfo));
			}

			function getSystemInfo() {
				var systemInfo = getItemFromSession(StorageConstants.SYSTEM_INFO_STORAGE_KEY) || "{}";
				return angular.fromJson(systemInfo);
			}

			function saveUserInfo(userInfo) {
				if (userInfo)
					setItemToSession(StorageConstants.USER_INFO_STORAGE_KEY, angular.toJson(userInfo));
			}

			function getUserInfo() {
				var userInfo = getItemFromSession(StorageConstants.USER_INFO_STORAGE_KEY) || "{}";
				return angular.fromJson(userInfo);
			}

			function saveFormatInfo(formatInfo) {
				if (formatInfo)
					setItemToSession(StorageConstants.FORMAT_INFO_STORAGE_KEY, angular.toJson(formatInfo));
			}

			function getFormatInfo() {
				var formatInfo = getItemFromSession(StorageConstants.FORMAT_INFO_STORAGE_KEY) || "{}";
				return angular.fromJson(formatInfo);
			}

			function saveMenuInfo(menuInfo) {
				if (menuInfo)
					setItemToSession(StorageConstants.MENU_INFO_STORAGE_KEY, angular.toJson(menuInfo));
			}

			function getMenuInfo() {
				var menuInfo = getItemFromSession(StorageConstants.MENU_INFO_STORAGE_KEY) || "[]";
				return angular.fromJson(menuInfo);
			}
			
			function saveMenuConfigInfo(menuInfo) {
				if (menuInfo)
					setItemToSession(StorageConstants.MENU_CONFIG_INFO_STORAGE_KEY, angular.toJson(menuInfo));
			}

			function getMenuConfigInfo() {
				var menuInfo = getItemFromSession(StorageConstants.MENU_CONFIG_INFO_STORAGE_KEY) || "[]";
				return angular.fromJson(menuInfo);
			}
			
			function saveDbdPanelSetting(pagePanelId, setting) {
				pagePanelId = $filter('encode')(pagePanelId);
				var userInfo = getUserInfo();
				/*var panelSetting = getDbdPanelSetting(pagePanelId);
				angular.merge(panelSetting, setting);*/
				setting.id = userInfo.userId + ":" + userInfo.workingCompanyCode + ':' + pagePanelId;
				saveDbdPanelConfig(setting);
			}
			
			function getDbdPanelSetting(pagePanelId) {
				pagePanelId = $filter('encode')(pagePanelId);
				var panelSettings = getItemFromLocal(StorageConstants.DBD_PANEL_KEY) || "{}";
				var userInfo = getUserInfo();
				panelSettings = angular.fromJson(panelSettings);
				return (panelSettings[userInfo.userId + ":" + userInfo.workingCompanyCode + ':' + pagePanelId] || panelSettings[userInfo.userId + ":" + userInfo.homeCompanyCode + ':' + pagePanelId]) || {};
			}
			
			function saveDbdPanelConfig(setting) {
				var panelSettings = getItemFromLocal(StorageConstants.DBD_PANEL_KEY) || "{}";
				panelSettings = angular.fromJson(panelSettings);
				panelSettings[setting.id] = setting;
				setItemToLocal(StorageConstants.DBD_PANEL_KEY, angular.toJson(panelSettings));
			}
			
			function saveTableSetting(tableId, setting) {
				var userInfo = getUserInfo();
				var tableSetting = getTableSetting(tableId);
				if (setting.visible) {
					if (tableSetting.visible) {
						angular.merge(tableSetting.visible, setting.visible);
					} else {
						tableSetting.visible = setting.visible;
					}
				}
				tableSetting.order = setting.order || tableSetting.order;
				if (setting.width) {
					if (tableSetting.width) {
						angular.merge(tableSetting.width, setting.width);
					} else {
						tableSetting.width = setting.width;
					}
				}
				tableSetting.id = userInfo.userId + ':' + tableId;
				saveTableConfig(tableSetting);
			}

			function getTableSetting(tableId) {
				var tableSettings = getItemFromLocal(StorageConstants.TABLE_KEY) || "{}";
				var userInfo = getUserInfo();
				tableSettings = angular.fromJson(tableSettings);
				return tableSettings[userInfo.userId + ':' + tableId] || {};
			}
			
			function saveTableConfig(setting) {
				var tableSettings = getItemFromLocal(StorageConstants.TABLE_KEY) || "{}";
				tableSettings = angular.fromJson(tableSettings);
				tableSettings[setting.id] = setting;
				setItemToLocal(StorageConstants.TABLE_KEY, angular.toJson(tableSettings));
			}

			function saveHistory(historyObj) {
				var histories = getItemFromSession(StorageConstants.BACKHIS_STORAGE_KEY) || "[]";
				histories = angular.fromJson(histories);
				if (histories.length < privoder.getHisStorageSize()) {
					histories.push(historyObj);
				} else {
					histories.shift();
					histories.push(historyObj);
				}
				setItemToSession(StorageConstants.BACKHIS_STORAGE_KEY, angular.toJson(histories));
			}

			function popHistory() {
				var history, histories = getItemFromSession(StorageConstants.BACKHIS_STORAGE_KEY) || "[]";
				histories = angular.fromJson(histories);
				if(histories && histories.length > 0){
					history = histories.pop();
					setItemToSession(StorageConstants.BACKHIS_STORAGE_KEY, angular.toJson(histories));
				}
				return history;
			}
			
			function getLastHistory() {
				var history, histories = getItemFromSession(StorageConstants.BACKHIS_STORAGE_KEY) || "[]";
				histories = angular.fromJson(histories);
				if(histories && histories.length > 0){
					history = histories[histories.length -1 ];
				}
				return history;
			}

			function getSystemSettings() {
				var settings = getItemFromLocal(StorageConstants.SYSTEM_SETTINGS_KEY);
				return angular.fromJson(settings);
			}
			

			function saveSystemSettings(settings) {
				var t;
				if (settings) {
					t = angular.copy(settings);
					if (t.settings) {
						delete t.settings.theme;
						delete t.settings.full;
					}
					if (t.logo) {
						delete t.logo;
					}
					setItemToLocal(StorageConstants.SYSTEM_SETTINGS_KEY, angular.toJson(t));
				}
			}
			function formatDate(object) {
				var formatter = getFormatInfo().longTimestamp;
				var formatService = $injector.get('formatService');
				function format(object) {
					angular.forEach(object, function(value, key) {
						if (!object.hasOwnProperty(key))
							return;
						if (angular.isDate(value)) {
							object[key] = formatService.formatDate(value, formatter);
						} else if (angular.isObject(value)) {
							format(value);
						}
					});
				}
				format(object);
				return object;
			}
			function parseDate(object) {
				var formatter = getFormatInfo().longTimestamp;
				var formatService = $injector.get('formatService');
				var fsDatePattern = new RegExp(formatter.replace('.', '\\.').replace(/[ydhHMmsS]/g, '\\d').replace(/Z/g, '[-+]\\d{4}'));
				function parse(object) {
					angular.forEach(object, function(value, key) {
						if (!object.hasOwnProperty(key))
							return;
						if (angular.isString(value) && fsDatePattern.test(value)) {
							object[key] = formatService.parseDate(value, formatter);
						} else if (angular.isObject(value)) {
							parse(value);
						}
					});
				}
				parse(object);
				return object;
			}
		} ];

	}
})(angular);
